from flask import request
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, TextAreaField, SelectField, RadioField, FileField, IntegerField, DecimalField, SelectMultipleField
from wtforms.validators import DataRequired, Length, ValidationError, URL
from flask_wtf.file import FileRequired, FileAllowed
from app.models import Admin

''' 自定义验证器 '''
class AdminValidate(object):
    def __init__(self, username_field, message=None) -> None:
        self.username_field = username_field
        self.message = message
    
    def __call__(self, form, field):
        username = form[self.username_field].data
        admin_id = request.args.get('id', 0, type=int)
        if not admin_id:
            admin = Admin.query.filter_by(username=username).first()
        else:
            admin = Admin.query.filter(Admin.username==username, Admin.id != admin_id).first()

        if admin:
            raise ValidationError(self.message)
        else:
            return True

class PasswordValidate(object):

    def __init__(self, password_field, message) -> None:
        self.password_field = password_field
        self.message = message
    
    def __call__(self, form, field):
        password = form[self.password_field].data
        admin_id = request.args.get('id', 0, type=int)
        if not admin_id:
            if not password:
                raise ValidationError(self.message[0])
            if len(password) < 5 or len(password) > 12:
                raise ValidationError(self.message[1])
            return True
        else:
            if password:
                if len(password) < 5 or len(password) > 12:
                    raise ValidationError(self.message[1])
            return True

class AdminForm(FlaskForm):
    username = StringField(label="用户名", validators=[DataRequired("请输入用户名"), Length(5, 10, "用户名大于5个字符"), AdminValidate("username", "用户名已经存在")])
    password = PasswordField(label="密码", validators=[PasswordValidate("password", ("请输入密码", "密码大于5个字符"))])
    submit = SubmitField(label="保存信息")

class TagForm(FlaskForm):
    tagname = StringField(label="标签名称", validators=[DataRequired("请输入标签名称")])
    submit = SubmitField(label="保存信息")

class LinkForm(FlaskForm):
    linkname = StringField(label="链接名称", validators=[DataRequired("请输入链接名称")])
    url = StringField(label="链接地址", validators=[DataRequired("请输入链接地址"), URL(True, '地址不合法')])
    description = TextAreaField(label="描述", validators=[])
    sort = IntegerField(label="排序")
    submit = SubmitField(label="保存信息")

class CategoryForm(FlaskForm):
    catname = StringField(label="栏目名称", validators=[DataRequired("请输入栏目名称")])
    sort = IntegerField(label="排序")
    submit = SubmitField(label="保存信息")


class ArticleFileValidate(object):
    def __init__(self, file_field, message) -> None:
        self.file_field = file_field
        self.message = message

    def __call__(self, form, field):
        file = form[self.file_field].data
        article_id = request.args.get('id', 0, type=int)
        if not article_id:
            if not file.filename:
                raise ValidationError(self.message)
        return True
    
class ArticleForm(FlaskForm):
    title = StringField(label="标题", validators=[DataRequired("请输入标题")])
    author = StringField(label="作者", validators=[DataRequired("请输入作者")])
    description = StringField(label="文章描述", validators=[DataRequired("请输入文章描述")])
    content = TextAreaField(label="文章内容", validators=[DataRequired("请输入文章内容")])
    category_id = SelectField(label="栏目", validators=[DataRequired("请选择栏目")], choices=[], coerce=int)
    keywords = SelectMultipleField(label="关键词", validators=[DataRequired("请选择标签")], choices=[], coerce=int)
    click = IntegerField(label="点击数")
    is_state = RadioField(label="是否推荐", choices=[(1, "是"), (0, "否")], coerce=int, validators=[])
    pic = FileField(label="缩略图", validators=[ArticleFileValidate("pic", "请上传缩略图"), FileAllowed(["png", "jpg", "gif", "jpeg"], message="图片格式错误")])
    submit = SubmitField(label="保存信息")

class LoginForm(FlaskForm):
    username = StringField(label="用户名", validators=[DataRequired("请输入用户名")])
    password = PasswordField(label="密码", validators=[DataRequired("请输入密码")])
    submit = SubmitField(label="Login")